package com.alan.nio.nionetwork;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 *  使用NIO完成网络通信的三个核心
 *
 * Buffer:负责数据的存储
 * Channel:负责连接
 * Selector：多路复用器，监控SelectableChannel的
 *
 * Created by Alan on 2017/8/10.
 */
public class Server {

    public static void main(String[] args) throws IOException {
        // 1. 获取通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        // 2. 绑定端口号
        serverSocketChannel.bind(new InetSocketAddress(9999));

        // 3.把通道切换为非阻塞
        serverSocketChannel.configureBlocking(false);

        //4.获取选择器
        Selector selector = Selector.open();

        //5.将通道注册到选择器上并且指定监听事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        //6.轮询式的获取选择器上已经就绪的事件
        while (selector.select() > 0){

            //7.获取当前选择器上的所有注册的选择键
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();

            while (it.hasNext()){

                //8.依次获取选择器中所有注册的选择键
                SelectionKey key = it.next();

                //9.判断具体是什么事件准备就绪
                if(key.isAcceptable()){

                    SocketChannel channel = serverSocketChannel.accept();

                    channel.configureBlocking(false);

                    channel.register(selector,SelectionKey.OP_READ );

                }else if(key.isReadable()){

                    SocketChannel channel = (SocketChannel) key.channel();

                    ByteBuffer buffer = ByteBuffer.allocate(1024);

                    int len;
                    while ((len = channel.read(buffer)) > 0){
                        buffer.flip();
                        System.out.println(new String(buffer.array(),0,len));
                        buffer.clear();
                    }
                }
                //已经处理过了
                it.remove();
            }
        }

    }

}
